/**
 * 
 */
package com.cn.practice.clone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 克隆模式
 * @author zhangyang
 *
 */
public class SheepClone {
	public static void main(String[] args) {
		/**
		 * 不使用克隆模式，显示克隆羊多莉
		 * 不停的new new对象时获取第一个属性
		 */
		Sheep sheep1 = new Sheep("多莉",12,"女",new Duck("BOB","172"));
		Sheep sheep2 = new Sheep(sheep1.getName(),sheep1.getAge(),sheep1.getSex());
		Sheep sheep3 = new Sheep(sheep1.getName(),sheep1.getAge(),sheep1.getSex());
		Sheep sheep4 = new Sheep(sheep1.getName(),sheep1.getAge(),sheep1.getSex());
		try {
			/**
			 * 使用克隆模式 用Object的克隆方法来实现对象克隆
			 */
			/**
			 * 浅度克隆实验-这里clone方法代码没有修改
			 */
			Sheep sheep5 = (Sheep)sheep1.clone();
			System.out.println(sheep5.getDuck()==sheep1.getDuck());
			System.out.println(sheep5.toString());
			/**
			 * 深度克隆-通过修改clone方法实现克隆，代码少但是如果需要克隆对象比较多比较麻烦
			 */
			System.out.println(sheep5.getDuck()==sheep1.getDuck());
			/**
			 * 深度克隆-序列化反序列化实现
			 */
			Sheep sheep6 = (Sheep)sheep1.deepClone();
			System.out.println(sheep6.getDuck()==sheep1.getDuck());
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
class Sheep implements Cloneable,Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String name;
	
	private int age;
	
	private String sex;

	private Duck duck;
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}
	
	
	public Duck getDuck() {
		return duck;
	}

	public void setDuck(Duck duck) {
		this.duck = duck;
	}

	public Sheep() {
		super();
	}
	
	public Sheep(String name, int age, String sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	
	public Sheep(String name, int age, String sex, Duck duck) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.duck = duck;
	}


	@Override
	public String toString() {
		return "Sheep [name=" + name + ", age=" + age + ", sex=" + sex + ", duck=" + duck + "]";
	}

	/**
	 * 深度克隆-修改clone方法
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
//		return super.clone();
		Sheep clone = (Sheep)super.clone();
		Duck duck = (Duck)clone.duck.clone();
		clone.duck=duck;
		return clone;
	}
	
	/**
	 * 深度克隆，通过序列化和反序列化实现
	 */
	public Object deepClone() {
		//序列化
		ByteArrayOutputStream bos;
		ObjectOutputStream oos;
		ByteArrayInputStream bis;
		ObjectInputStream ois;
		try {
			bos=new ByteArrayOutputStream();
			oos=new ObjectOutputStream(bos);
			//首先将这个对象序列化
			oos.writeObject(this);
			//将输出流转成输入流
			bis=new ByteArrayInputStream(bos.toByteArray());
			//然后在反序列化这个对象
			ois=new ObjectInputStream(bis);
			Object object = ois.readObject();
			return object;
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return null;
	}
}

class Duck implements Cloneable,Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private String height;
	public Duck(String name, String height) {
		super();
		this.name = name;
		this.height = height;
	}
	public Duck() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getHeight() {
		return height;
	}
	public void setHeight(String height) {
		this.height = height;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	@Override
	public String toString() {
		return "Duck [name=" + name + ", height=" + height + "]";
	}
	
	
}
	